home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / ruby / 1.8 / finalize.rb < prev    next >
Text File  |  2007-02-12  |  6KB  |  194 lines

  1. #--
  2. #   finalizer.rb - 
  3. #       $Release Version: 0.3$
  4. #       $Revision: 1.4 $
  5. #       $Date: 1998/02/27 05:34:33 $
  6. #       by Keiju ISHITSUKA
  7. #++
  8. #
  9. # Usage:
  10. #
  11. # add dependency R_method(obj, dependant)
  12. #   add(obj, dependant, method = :finalize, *opt)
  13. #   add_dependency(obj, dependant, method = :finalize, *opt)
  14. #
  15. # delete dependency R_method(obj, dependant)
  16. #   delete(obj_or_id, dependant, method = :finalize)
  17. #   delete_dependency(obj_or_id, dependant, method = :finalize)
  18. #
  19. # delete dependency R_*(obj, dependant)
  20. #   delete_all_dependency(obj_or_id, dependant)
  21. #
  22. # delete dependency R_method(*, dependant)
  23. #   delete_by_dependant(dependant, method = :finalize)
  24. #
  25. # delete dependency R_*(*, dependant)
  26. #   delete_all_by_dependant(dependant)
  27. #
  28. # delete all dependency R_*(*, *)
  29. #   delete_all
  30. #
  31. # finalize the dependant connected by dependency R_method(obj, dependtant).
  32. #   finalize(obj_or_id, dependant, method = :finalize)
  33. #   finalize_dependency(obj_or_id, dependant, method = :finalize)
  34. #
  35. # finalize all dependants connected by dependency R_*(obj, dependtant).
  36. #   finalize_all_dependency(obj_or_id, dependant)
  37. #
  38. # finalize the dependant connected by dependency R_method(*, dependtant).
  39. #   finalize_by_dependant(dependant, method = :finalize)
  40. #
  41. # finalize all dependants connected by dependency R_*(*, dependant).
  42. #   finalize_all_by_dependant(dependant)
  43. #
  44. # finalize all dependency registered to the Finalizer.
  45. #   finalize_all
  46. #
  47. # stop invoking Finalizer on GC.
  48. #   safe{..}
  49. #
  50.  
  51. module Finalizer
  52.   RCS_ID='-$Id: finalize.rb,v 1.4 1998/02/27 05:34:33 keiju Exp keiju $-'
  53.  
  54.   class <<self
  55.     # @dependency: {id => [[dependant, method, *opt], ...], ...}
  56.  
  57.     # add dependency R_method(obj, dependant)
  58.     def add_dependency(obj, dependant, method = :finalize, *opt)
  59.       ObjectSpace.call_finalizer(obj)
  60.       method = method.intern unless method.kind_of?(Integer)
  61.       assoc = [dependant, method].concat(opt)
  62.       if dep = @dependency[obj.object_id]
  63.     dep.push assoc
  64.       else
  65.     @dependency[obj.object_id] = [assoc]
  66.       end
  67.     end
  68.     alias add add_dependency
  69.  
  70.     # delete dependency R_method(obj, dependant)
  71.     def delete_dependency(id, dependant, method = :finalize)
  72.       id = id.object_id unless id.kind_of?(Integer)
  73.       method = method.intern unless method.kind_of?(Integer)
  74.       for assoc in @dependency[id]
  75.     assoc.delete_if do
  76.       |d, m, *o|
  77.       d == dependant && m == method
  78.     end
  79.     @dependency.delete(id) if assoc.empty?
  80.       end
  81.     end
  82.     alias delete delete_dependency
  83.  
  84.     # delete dependency R_*(obj, dependant)
  85.     def delete_all_dependency(id, dependant)
  86.       id = id.object_id unless id.kind_of?(Integer)
  87.       method = method.intern unless method.kind_of?(Integer)
  88.       for assoc in @dependency[id]
  89.     assoc.delete_if do
  90.       |d, m, *o|
  91.       d == dependant
  92.     end
  93.     @dependency.delete(id) if assoc.empty?
  94.       end
  95.     end
  96.  
  97.     # delete dependency R_method(*, dependant)
  98.     def delete_by_dependant(dependant, method = :finalize)
  99.       method = method.intern unless method.kind_of?(Integer)
  100.       for id in @dependency.keys
  101.     delete(id, dependant, method)
  102.       end
  103.     end
  104.  
  105.     # delete dependency R_*(*, dependant)
  106.     def delete_all_by_dependant(dependant)
  107.       for id in @dependency.keys
  108.     delete_all_dependency(id, dependant)
  109.       end
  110.     end
  111.  
  112.     # finalize the depandant connected by dependency R_method(obj, dependtant)
  113.     def finalize_dependency(id, dependant, method = :finalize)
  114.       id = id.object_id unless id.kind_of?(Integer)
  115.       method = method.intern unless method.kind_of?(Integer)
  116.       for assocs in @dependency[id]
  117.     assocs.delete_if do
  118.       |d, m, *o|
  119.       d.send(m, id, *o) if ret = d == dependant && m == method
  120.       ret
  121.     end
  122.     @dependency.delete(id) if assoc.empty?
  123.       end
  124.     end
  125.     alias finalize finalize_dependency
  126.  
  127.     # finalize all dependants connected by dependency R_*(obj, dependtant)
  128.     def finalize_all_dependency(id, dependant)
  129.       id = id.object_id unless id.kind_of?(Integer)
  130.       method = method.intern unless method.kind_of?(Integer)
  131.       for assoc in @dependency[id]
  132.     assoc.delete_if do
  133.       |d, m, *o|
  134.       d.send(m, id, *o) if ret = d == dependant
  135.     end
  136.     @dependency.delete(id) if assoc.empty?
  137.       end
  138.     end
  139.  
  140.     # finalize the dependant connected by dependency R_method(*, dependtant)
  141.     def finalize_by_dependant(dependant, method = :finalize)
  142.       method = method.intern unless method.kind_of?(Integer)
  143.       for id in @dependency.keys
  144.     finalize(id, dependant, method)
  145.       end
  146.     end
  147.  
  148.     # finalize all dependants connected by dependency R_*(*, dependtant)
  149.     def finalize_all_by_dependant(dependant)
  150.       for id in @dependency.keys
  151.     finalize_all_dependency(id, dependant)
  152.       end
  153.     end
  154.  
  155.     # finalize all dependants registered to the Finalizer.
  156.     def finalize_all
  157.       for id, assocs in @dependency
  158.     for dependant, method, *opt in assocs
  159.       dependant.send(method, id, *opt)
  160.     end
  161.     assocs.clear
  162.       end
  163.     end
  164.  
  165.     # method to call finalize_* safely.
  166.     def safe
  167.       old_status = Thread.critical
  168.       Thread.critical = true
  169.       ObjectSpace.remove_finalizer(@proc)
  170.       begin
  171.     yield
  172.       ensure
  173.     ObjectSpace.add_finalizer(@proc)
  174.     Thread.critical = old_status
  175.       end
  176.     end
  177.  
  178.     private
  179.  
  180.     # registering function to ObjectSpace#add_finalizer
  181.     def final_of(id)
  182.       if assocs = @dependency.delete(id)
  183.     for dependant, method, *opt in assocs
  184.       dependant.send(method, id, *opt)
  185.     end
  186.       end
  187.     end
  188.  
  189.   end
  190.   @dependency = Hash.new
  191.   @proc = proc{|id| final_of(id)}
  192.   ObjectSpace.add_finalizer(@proc)
  193. end
  194.